package com.it.schoolhomeos.controller;

import com.it.schoolhomeos.dto.ApiResponse;
import com.it.schoolhomeos.entity.Attendance;
import com.it.schoolhomeos.entity.ClassInfo;
import com.it.schoolhomeos.entity.Grade;
import com.it.schoolhomeos.entity.Student;
import com.it.schoolhomeos.entity.User;
import com.it.schoolhomeos.service.AttendanceService;
import com.it.schoolhomeos.service.GradeService;
import com.it.schoolhomeos.service.StudentService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

import com.it.schoolhomeos.dto.StudentAttendanceDTO;

/**
 * 学生控制器
 * 
 * 处理学生信息、考勤、成绩等相关操作
 * 提供学生管理、查询学生考勤和成绩的功能
 */
@RestController
@RequestMapping("/api")
@Tag(name = "学生管理", description = "学生信息的增删改查接口")
public class StudentController {

    /**
     * 学生服务，用于处理学生基本信息相关业务逻辑
     */
    @Autowired
    private StudentService studentService;
    
    /**
     * 考勤服务，用于处理学生考勤相关业务逻辑
     */
    @Autowired
    private AttendanceService attendanceService;
    
    /**
     * 成绩服务，用于处理学生成绩相关业务逻辑
     */
    @Autowired
    private GradeService gradeService;

    // 辅助方法：将英文月份转换为数字
    private String convertMonth(String month) {
        switch (month.toLowerCase()) {
            case "jan": return "01";
            case "feb": return "02";
            case "mar": return "03";
            case "apr": return "04";
            case "may": return "05";
            case "jun": return "06";
            case "jul": return "07";
            case "aug": return "08";
            case "sep": return "09";
            case "oct": return "10";
            case "nov": return "11";
            case "dec": return "12";
            default: return "01"; // 默认返回1月
        }
    }

    // 管理员接口
    @GetMapping("/admin/students")
    @Operation(summary = "管理员获取学生列表", description = "管理员获取所有学生列表，可按条件筛选")
    @PreAuthorize("hasRole('ADMIN')")
    public ResponseEntity<Map<String, Object>> getAllStudentsByAdmin(
            @Parameter(description = "班级ID") @RequestParam(required = false) Long classId,
            @Parameter(description = "家长ID") @RequestParam(required = false) Long parentId,
            @Parameter(description = "搜索关键词（学生姓名、学号、电话）") @RequestParam(required = false) String keyword,
            @Parameter(description = "页码") @RequestParam(defaultValue = "0") int page,
            @Parameter(description = "每页大小") @RequestParam(defaultValue = "10") int size) {
        
        System.out.println("接收到学生查询请求 - 关键字: " + keyword + ", 班级ID: " + classId + ", 家长ID: " + parentId);
        
        Page<Student> students = studentService.getStudents(classId, parentId, keyword, page, size);
        
        return ResponseEntity.ok(Map.of(
            "status", "success",
            "message", "获取学生列表成功",
            "data", students
        ));
    }

    @GetMapping("/admin/students/{id}")
    @Operation(summary = "管理员获取学生详情", description = "管理员根据ID获取学生详细信息")
    @PreAuthorize("hasRole('ADMIN')")
    public ResponseEntity<Map<String, Object>> getStudentByIdAdmin(@PathVariable Long id) {
        Student student = studentService.findById(id);
        return ResponseEntity.ok(Map.of(
            "status", "success",
            "message", "获取学生详情成功",
            "data", student
        ));
    }

    @PostMapping("/admin/students")
    @Operation(summary = "创建学生", description = "管理员创建新的学生")
    @PreAuthorize("hasRole('ADMIN')")
    public ResponseEntity<Map<String, Object>> createStudentByAdmin(@RequestBody Map<String, Object> requestData) {
        try {
            Student student = new Student();
            
            // 设置基本信息
            student.setName((String) requestData.get("name"));
            student.setGender((String) requestData.get("gender"));
            
            // 设置学号 - 生成一个唯一的学号
            String studentNumber = "S" + System.currentTimeMillis();
            student.setStudentNumber(studentNumber);
            
            // 设置出生日期
            if (requestData.get("birthday") != null) {
                try {
                    String birthdayStr = requestData.get("birthday").toString();
                    // 前端已经格式化为 YYYY-MM-DD 格式
                    LocalDateTime birthDate = LocalDateTime.parse(birthdayStr + "T00:00:00");
                    student.setBirthDate(birthDate);
                } catch (Exception e) {
                    // 日期解析失败，忽略此字段
                    System.out.println("日期解析失败: " + e.getMessage());
                }
            }
            
            // 设置班级信息
            if (requestData.get("classId") != null) {
                Long classId = Long.valueOf(requestData.get("classId").toString());
                ClassInfo classInfo = new ClassInfo();
                classInfo.setId(classId);
                student.setClassInfo(classInfo);
            }
            
            // 设置家长信息（如果有）
            if (requestData.get("parentId") != null) {
                Long parentId = Long.valueOf(requestData.get("parentId").toString());
                User parent = new User();
                parent.setId(parentId);
                student.setParent(parent);
            }
            
            // 设置其他可选字段
            if (requestData.get("phone") != null) {
                student.setPhone((String) requestData.get("phone"));
            }
            
            if (requestData.get("address") != null) {
                student.setAddress((String) requestData.get("address"));
            }
            
            if (requestData.get("remarks") != null) {
                student.setRemarks((String) requestData.get("remarks"));
            }
            
            // 设置创建时间和更新时间
            LocalDateTime now = LocalDateTime.now();
            student.setCreateTime(now);
            student.setUpdateTime(now);
            
            Student savedStudent = studentService.save(student);
            return ResponseEntity.ok(Map.of(
                "status", "success",
                "message", "创建学生成功",
                "data", savedStudent
            ));
        } catch (Exception e) {
            return ResponseEntity.badRequest().body(Map.of(
                "status", "error",
                "message", "创建学生失败: " + e.getMessage()
            ));
        }
    }

    @PutMapping("/admin/students/{id}")
    @Operation(summary = "更新学生", description = "管理员更新现有学生信息")
    @PreAuthorize("hasRole('ADMIN')")
    public ResponseEntity<Map<String, Object>> updateStudentByAdmin(
            @PathVariable Long id, 
            @RequestBody Map<String, Object> requestData) {
        try {
            // 先获取原有的学生信息
            Student existingStudent = studentService.findById(id);
            if (existingStudent == null) {
                return ResponseEntity.badRequest().body(Map.of(
                    "status", "error",
                    "message", "学生不存在"
                ));
            }
            
            // 创建新的学生对象，保留原有信息
            Student student = new Student();
            student.setId(id);
            student.setStudentNumber(existingStudent.getStudentNumber());
            student.setCreateTime(existingStudent.getCreateTime());
            student.setUpdateTime(LocalDateTime.now());
            
            // 保留原有的班级信息
            student.setClassInfo(existingStudent.getClassInfo());
            
            // 更新基本信息
            if (requestData.get("name") != null) {
                student.setName((String) requestData.get("name"));
            } else {
                student.setName(existingStudent.getName());
            }
            
            if (requestData.get("gender") != null) {
                student.setGender((String) requestData.get("gender"));
            } else {
                student.setGender(existingStudent.getGender());
            }
            
            // 更新出生日期
            if (requestData.get("birthday") != null) {
                try {
                    String birthdayStr = requestData.get("birthday").toString();
                    // 前端已经格式化为 YYYY-MM-DD 格式
                    LocalDateTime birthDate = LocalDateTime.parse(birthdayStr + "T00:00:00");
                    student.setBirthDate(birthDate);
                } catch (Exception e) {
                    // 日期解析失败，保留原有日期
                    student.setBirthDate(existingStudent.getBirthDate());
                }
            } else {
                student.setBirthDate(existingStudent.getBirthDate());
            }
            
            // 更新班级信息（如果提供了）
            if (requestData.get("classId") != null) {
                Long classId = Long.valueOf(requestData.get("classId").toString());
                ClassInfo classInfo = new ClassInfo();
                classInfo.setId(classId);
                student.setClassInfo(classInfo);
            }
            
            // 更新家长信息（如果提供了）
            if (requestData.get("parentId") != null) {
                Long parentId = Long.valueOf(requestData.get("parentId").toString());
                User parent = new User();
                parent.setId(parentId);
                student.setParent(parent);
            } else {
                student.setParent(existingStudent.getParent());
            }
            
            // 更新其他可选字段
            if (requestData.get("phone") != null) {
                student.setPhone((String) requestData.get("phone"));
            } else {
                student.setPhone(existingStudent.getPhone());
            }
            
            if (requestData.get("address") != null) {
                student.setAddress((String) requestData.get("address"));
            } else {
                student.setAddress(existingStudent.getAddress());
            }
            
            if (requestData.get("remarks") != null) {
                student.setRemarks((String) requestData.get("remarks"));
            } else {
                student.setRemarks(existingStudent.getRemarks());
            }
            
            Student updatedStudent = studentService.update(student);
            return ResponseEntity.ok(Map.of(
                "status", "success",
                "message", "更新学生成功",
                "data", updatedStudent
            ));
        } catch (Exception e) {
            return ResponseEntity.badRequest().body(Map.of(
                "status", "error",
                "message", "更新学生失败: " + e.getMessage()
            ));
        }
    }

    @DeleteMapping("/admin/students/{id}")
    @Operation(summary = "删除学生", description = "管理员删除指定的学生")
    @PreAuthorize("hasRole('ADMIN')")
    public ResponseEntity<Map<String, Object>> deleteStudentByAdmin(@PathVariable Long id) {
        studentService.deleteById(id);
        return ResponseEntity.ok(Map.of(
            "status", "success",
            "message", "删除学生成功"
        ));
    }

    @GetMapping("/teacher/students")
    @Operation(summary = "获取学生列表", description = "获取当前教师所教班级的学生列表")
    @PreAuthorize("hasRole('TEACHER')")
    public ResponseEntity<Map<String, Object>> getAllStudents() {
        List<Student> students = studentService.findByCurrentTeacher();
        return ResponseEntity.ok(Map.of(
            "status", "success",
            "message", "获取学生列表成功",
            "data", students
        ));
    }

    @GetMapping("/teacher/students/{id}")
    @Operation(summary = "获取学生详情", description = "教师根据ID获取学生详细信息")
    @PreAuthorize("hasRole('TEACHER')")
    public ResponseEntity<Map<String, Object>> getStudentById(@PathVariable Long id) {
        Student student = studentService.findById(id);
        return ResponseEntity.ok(Map.of(
            "status", "success",
            "message", "获取学生详情成功",
            "data", student
        ));
    }

    // 家长访问接口
    @GetMapping("/parent/students")
    @Operation(summary = "家长获取学生列表", description = "获取当前家长关联的学生列表")
    @PreAuthorize("hasRole('PARENT')")
    public ResponseEntity<Map<String, Object>> getStudentsByParent() {
        List<Student> students = studentService.findByCurrentParent();
        return ResponseEntity.ok(Map.of(
            "status", "success",
            "message", "获取学生列表成功",
            "data", students
        ));
    }

    @GetMapping("/parent/students/{id}")
    @Operation(summary = "家长获取学生详情", description = "家长获取指定学生的详细信息")
    @PreAuthorize("hasRole('PARENT')")
    public ResponseEntity<Map<String, Object>> getStudentByParent(@PathVariable Long id) {
        Student student = studentService.findByIdAndCurrentParent(id);
        return ResponseEntity.ok(Map.of(
            "status", "success",
            "message", "获取学生详情成功",
            "data", student
        ));
    }

    /**
     * 获取学生列表接口
     * 
     * @param classId 班级ID，可选参数
     * @param parentId 家长ID，可选参数
     * @param page 页码，默认为0
     * @param size 每页大小，默认为10
     * @return 分页的学生列表
     */
    @GetMapping
    @Operation(summary = "获取学生列表", description = "分页获取学生列表")
    public ApiResponse<Page<Student>> getStudents(
            @Parameter(description = "班级ID") @RequestParam(required = false) Long classId,
            @Parameter(description = "家长ID") @RequestParam(required = false) Long parentId,
            @Parameter(description = "页码") @RequestParam(defaultValue = "0") int page,
            @Parameter(description = "每页大小") @RequestParam(defaultValue = "10") int size) {
        
        Page<Student> students = studentService.getStudents(classId, parentId, page, size);
        return ApiResponse.success(students);
    }

    /**
     * 获取学生考勤记录接口
     * 
     * @param id 学生ID
     * @param startDate 开始日期，可选参数
     * @param endDate 结束日期，可选参数
     * @return 学生考勤记录列表
     */
    @GetMapping("/{id}/attendance")
    @Operation(summary = "获取学生考勤", description = "获取指定学生的考勤记录")
    public ApiResponse<List<StudentAttendanceDTO>> getStudentAttendance(
            @PathVariable Long id,
            @Parameter(description = "开始日期") @RequestParam(required = false) LocalDate startDate,
            @Parameter(description = "结束日期") @RequestParam(required = false) LocalDate endDate) {
        
        List<StudentAttendanceDTO> attendance = attendanceService.getStudentAttendanceByParent(id, startDate, endDate);
        return ApiResponse.success(attendance);
    }
    
    /**
     * 获取学生成绩记录接口
     * 
     * @param id 学生ID
     * @param subject 科目，可选参数
     * @param examId 考试ID，可选参数
     * @return 学生成绩记录列表
     */
    @GetMapping("/{id}/grades")
    @Operation(summary = "获取学生成绩", description = "获取指定学生的成绩记录")
    public ApiResponse<List<Grade>> getStudentGrades(
            @PathVariable Long id,
            @Parameter(description = "科目") @RequestParam(required = false) String subject,
            @Parameter(description = "考试ID") @RequestParam(required = false) Long examId) {
        
        List<Grade> grades = gradeService.getStudentGrades(id, subject, examId);
        return ApiResponse.success(grades);
    }
} 